home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / swtools / libdwarf / pro_funcs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  5.9 KB  |  205 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <elfaccess.h>
  4. #include "pro_incl.h"
  5. #include "pro_funcs.h"
  6. #include "pro_section.h"
  7.  
  8. #define GET_DISP(dbg,val) (IS_64BIT(dbg) ? (char *)&val : ((char *)&val + 4))
  9.  
  10. extern int elf_sects[NUM_DEBUG_SECTIONS];
  11. extern int sect_name_idx[NUM_DEBUG_SECTIONS];
  12. extern int reloc_sects[NUM_DEBUG_SECTIONS];
  13.  
  14. /*
  15.     This function adds another function name to the 
  16.     list of function names for the given Dwarf_P_Debug.  
  17.     It returns 0 on error, and 1 otherwise.
  18. */
  19. Dwarf_Unsigned 
  20. dwarf_add_funcname (
  21.     Dwarf_P_Debug    dbg,
  22.     Dwarf_P_Die        die,
  23.     char        *function_name,
  24.     Dwarf_Error        *error
  25. )
  26. {
  27.     Dwarf_P_Funcname        funcname;
  28.     char            *name;
  29.  
  30.     if (dbg == NULL) {
  31.     _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
  32.     return(0);
  33.     }
  34.  
  35.     if (die == NULL) {
  36.     _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
  37.     return(0);
  38.     }
  39.  
  40.     funcname = (Dwarf_P_Funcname)
  41.     _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Funcname_s));
  42.     if (funcname == NULL) {
  43.     _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
  44.     return(0);
  45.     }
  46.  
  47.     name = _dwarf_p_get_alloc(dbg, strlen(function_name)+1);
  48.     if (name == NULL) {
  49.     _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
  50.     return(0);
  51.     }
  52.     strcpy(name, function_name);
  53.  
  54.     funcname->fu_die = die;
  55.     funcname->fu_name = name;
  56.  
  57.     if (dbg->de_funcname == NULL)
  58.     dbg->de_funcname = dbg->de_last_funcname = funcname;
  59.     else {
  60.     dbg->de_last_funcname->fu_next = funcname;
  61.     dbg->de_last_funcname = funcname;
  62.     }
  63.     dbg->de_funcname_count++;
  64.  
  65.     return(1);
  66. }
  67.  
  68.  
  69. int
  70. _dwarf_transform_funcname_to_disk (
  71.     Dwarf_P_Debug    dbg,
  72.     Dwarf_Error        *error
  73. )
  74. {
  75.     /* Total num of bytes in .debug_funcnames section. */
  76.     Dwarf_Unsigned    funcname_num_bytes;
  77.  
  78.     /* Total number of bytes excluding the length field. */
  79.     Dwarf_Unsigned    adjusted_length;
  80.  
  81.     /* Points to first byte of .debug_funcnames buffer. */
  82.     Dwarf_Small        *funcname;
  83.  
  84.     /* Scans the list of funcnames provided by user. */
  85.     Dwarf_P_Funcname    given_funcname;
  86.  
  87.     /* Fills in the .debug_funcnames buffer. */
  88.     Dwarf_Small        *funcname_ptr;
  89.  
  90.     /* Points to first byte of .rel.debug_funcnames section. */
  91.     Dwarf_Small        *funcname_reloc;
  92.  
  93.     /* Used to fill in 0. */
  94.     const Dwarf_Signed    big_zero = 0;
  95.  
  96.         /* Used to scan the section data buffers. */
  97.     Dwarf_P_Section_Data    debug_sect;
  98.  
  99.     /* Size of the .debug_info section. */
  100.     Dwarf_Signed    debug_info_size;
  101.  
  102.     /* Points to a Elf64_Rel record. */
  103.     Elf64_Rel        *elf64_reloc;
  104.  
  105.     /* Points to a Elf32_Rel record. */
  106.     Elf32_Rel        *elf32_reloc;
  107.  
  108.     int            name_idx;
  109.     int            err;
  110.  
  111.     /* ***** BEGIN CODE ***** */
  112.  
  113.     /* Get the size of the .debug_info section. */
  114.     debug_info_size = 0;
  115.     for (debug_sect = dbg->de_debug_sects; debug_sect != NULL;
  116.     debug_sect = debug_sect->ds_next) 
  117.     if (debug_sect->ds_elf_sect_no == elf_sects[DEBUG_INFO])
  118.         debug_info_size += debug_sect->ds_nbytes;
  119.  
  120.     /* Size of the .debug_funcnames section header. */
  121.     funcname_num_bytes = 
  122.     SIZEOF_UWORD(dbg) +      /* Size of length field. */
  123.     sizeof(Dwarf_Half) +    /* Size of version field. */
  124.     SIZEOF_UWORD(dbg) +     /* Size of .debug_info offset. */
  125.     SIZEOF_UWORD(dbg);      /* Size of .debug_info. */
  126.  
  127.     /* Add the size of the names portion. */
  128.     for (given_funcname = dbg->de_funcname; given_funcname != NULL; 
  129.     given_funcname = given_funcname->fu_next)
  130.     funcname_num_bytes += 
  131.         SIZEOF_UWORD(dbg) +             /* size of die offset. */
  132.         strlen(given_funcname->fu_name) + 1;    /* size of pub name. */
  133.  
  134.     /* Size of the last 0 offset. */
  135.     funcname_num_bytes += SIZEOF_UWORD(dbg);
  136.  
  137.     GET_NEW_CHUNK(dbg, elf_sects[DEBUG_FUNCNAMES], funcname, 
  138.     funcname_num_bytes, error);
  139.     if (funcname == NULL)
  140.     {_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return(0);}
  141.     funcname_ptr = funcname;
  142.  
  143.     /* Write the adjusted length of .debug_funcnames section. */
  144.     adjusted_length = funcname_num_bytes - SIZEOF_UWORD(dbg);
  145.     memcpy(funcname_ptr, GET_DISP(dbg, adjusted_length), SIZEOF_UWORD(dbg));
  146.     funcname_ptr += SIZEOF_UWORD(dbg);
  147.  
  148.     /* Write the version as 2 bytes. */
  149.     *funcname_ptr = 0;
  150.     funcname_ptr++;
  151.     *funcname_ptr = CURRENT_VERSION_STAMP;
  152.     funcname_ptr++;
  153.  
  154.     /* Write the offset of the compile-unit. */
  155.     memcpy(funcname_ptr, GET_DISP(dbg, big_zero), SIZEOF_UWORD(dbg));
  156.     funcname_ptr += SIZEOF_UWORD(dbg);
  157.  
  158.     /* Write the size of .debug_info. */
  159.     memcpy(funcname_ptr, GET_DISP(dbg, debug_info_size), SIZEOF_UWORD(dbg));
  160.     funcname_ptr += SIZEOF_UWORD(dbg);
  161.  
  162.     reloc_sects[DEBUG_FUNCNAMES] = dbg->de_func(".rel.debug_funcnames", 
  163.     IS_64BIT(dbg), SHT_REL, 0, SHN_UNDEF, elf_sects[DEBUG_FUNCNAMES], 
  164.     &name_idx, &err);
  165.     if (reloc_sects[DEBUG_FUNCNAMES] == -1) {
  166.         DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR, DW_DLV_NOCOUNT);
  167.     }
  168.  
  169.     GET_NEW_CHUNK(dbg, reloc_sects[DEBUG_FUNCNAMES], funcname_reloc, 
  170.     IS_64BIT(dbg)?sizeof(Elf64_Rel):sizeof(Elf32_Rel), error);
  171.     if (funcname_reloc == NULL) 
  172.     {_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return(0);}
  173.  
  174.     /* Write relocation record for .debug_info offset. */
  175.     if (IS_64BIT(dbg)) {
  176.     elf64_reloc = (Elf64_Rel *)funcname_reloc;
  177.     elf64_reloc->r_offset = SIZEOF_UWORD(dbg) + sizeof(Dwarf_Half);
  178.     Set_REL64_info
  179.         (*elf64_reloc, sect_name_idx[DEBUG_INFO], R_MIPS_64);
  180.     }
  181.     else {
  182.     elf32_reloc = (Elf32_Rel *)funcname_reloc;
  183.     elf32_reloc->r_offset = SIZEOF_UWORD(dbg) + sizeof(Dwarf_Half);
  184.     Set_REL32_info
  185.         (*elf32_reloc, sect_name_idx[DEBUG_INFO], R_MIPS_32);
  186.     }
  187.  
  188.     for (given_funcname = dbg->de_funcname; given_funcname != NULL;
  189.     given_funcname = given_funcname->fu_next) {
  190.  
  191.         /* Copy offset of die from start of compile-unit. */
  192.     memcpy(funcname_ptr, GET_DISP(dbg, given_funcname->fu_die->di_offset),
  193.         SIZEOF_UWORD(dbg));
  194.     funcname_ptr += SIZEOF_UWORD(dbg);
  195.  
  196.         /* Copy the function name. */
  197.     strcpy(funcname_ptr, given_funcname->fu_name);
  198.     funcname_ptr += strlen(given_funcname->fu_name) + 1;
  199.     }
  200.  
  201.     memcpy(funcname_ptr, GET_DISP(dbg, big_zero), SIZEOF_UWORD(dbg));
  202.  
  203.     return dbg->de_n_debug_sect;
  204. }
  205.